#ifndef XLCOMM_BASE_ASYNCLOG_H_
#define XLCOMM_BASE_ASYNCLOG_H_

#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

#include "xlcomm/base/count_down_latch.h"
#include "xlcomm/base/fix_buffer.h"
#include "xlcomm/base/sync_log.h"
#include "xlcomm/define.h"
#include "xlcomm/noncopyable.h"

namespace xlcomm {

// 线程安全的异步日志类（对象生命周期尽可能和整个程序一致）
class XLCOMM_API AsyncLog : noncopyable {
 public:
  explicit AsyncLog(const char* basename,
                    int64_t roll_size = 1024 * 1024 * 1024);
  ~AsyncLog();

  // 追加日志（后台线程异步写文件）
  void Append(const char* msg, size_t len);

  // 清空缓冲区，写到磁盘
  void Flush();

  // 设置刷新间隔，单位：s
  void set_flush_interval_second(int second) {
    flush_interval_second_ = second;
  }

 private:
  using Buffer = FixBuffer<kLargeBufferSize>;
  using BufferPtr = std::unique_ptr<Buffer>;

  // 启动后台写文件线程
  void Start();
  // 停止后台写文件线程
  void Stop();
  // 后台写文件线程处理函数
  void ThreadProc();

  SyncLog sync_log_;
  int flush_interval_second_;
  std::mutex mutex_;
  std::condition_variable condition_;
  CountDownLatch start_latch_;
  BufferPtr cur_buffer_;
  BufferPtr next_buffer_;
  std::vector<BufferPtr> buffers_queue_;
  std::thread write_thread_;
  std::atomic<bool> running_;
};

}  // namespace xlcomm

#endif  // XLCOMM_BASE_ASYNCLOG_H_